package com.ygqh.baby.utils;

import org.apache.commons.lang.time.DurationFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class DateConvertUtils {
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT_1 = "yyyy-MM-dd'T'HH:mm:ssXXX";
    public static final String DATE_FORMAT_CRON = "ss mm HH dd MM ? yyyy";
    public static final String MONTH_FORMAT = "yyyy-MM";

    public static String format(Date date) {
        return format(date, DATE_FORMAT);
    }

    public static String formatDateTime(Date date) {
        return format(date, DATE_TIME_FORMAT);
    }

    public static String format(Date date, String format) {
        if (date == null)
            return null;

        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    public static String format(Date date, String format, Locale locale) {
        if (date == null)
            return null;

        String timestamp = new SimpleDateFormat(format, Locale.ENGLISH).format(date);
        return timestamp;
    }

    public static Date formatToDate(Date date, String format) {
        if (date == null)
            return null;

        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        String s = dateFormat.format(date);
        Date t = null;
        try {
            t = dateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return t;
    }

    public static Date parse(String date, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        if (date == null || date.trim() == "")
            return null;
        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static long diffMinutes(Date t1, Date t2) {
        long tms1 = t1.getTime();
        long tms2 = t2.getTime();

        return (tms2 - tms1) / (1000 * 60);
    }

    public static long diffDayes(Date t1, Date t2) {
        long tms1 = t1.getTime();
        long tms2 = t2.getTime();

        return Math.abs((tms2 - tms1) / (1000 * 60 * 60 * 24));
    }

    public static long diffMonths(String t1, String t2) {
        Calendar cale1 = Calendar.getInstance();
        Calendar cale2 = Calendar.getInstance();
        cale1.setTime(parse(t1, MONTH_FORMAT));
        cale2.setTime(parse(t2, MONTH_FORMAT));
        int y1 = cale1.get(Calendar.YEAR);
        int y2 = cale2.get(Calendar.YEAR);
        int m1 = cale1.get(Calendar.MONTH);
        int m2 = cale2.get(Calendar.MONTH);
        return Math.abs((y2 - y1) * 12 + m2 - m1);
    }

    public static List<String> diffDay(String startDate, String endDate) {
        List<String> days = new ArrayList<String>();
        try {
            SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd");
            Calendar sta = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            Date startDay = dayFormat.parse(startDate);
            Date endDay = dayFormat.parse(endDate);
            sta.setTime(startDay);
            end.setTime(endDay);
            while (sta.compareTo(end) < 0) {
                sta.add(Calendar.DATE, 1);
                Date ss = sta.getTime();
                String str = dayFormat.format(ss);
                days.add(str);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return days;
    }

    public static List<String> diffMonth(String startDate, String endDate) {
        List<String> months = new ArrayList<String>();
        try {
            SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
            Date startDay = monthFormat.parse(startDate);
            Date endDay = monthFormat.parse(endDate);
            Calendar sta = Calendar.getInstance();
            Calendar end = Calendar.getInstance();

            sta.setTime(startDay);
            end.setTime(endDay);
            while (sta.compareTo(end) < 0) {
                sta.add(Calendar.MONTH, 1);
                Date ss = sta.getTime();
                String str = monthFormat.format(ss);
                months.add(str);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return months;
    }

    /**
     * 使用前看下是否试用，只是对年份的运算
     *
     * @param startDate
     * @param endDate
     * @return int 返回类型
     * @throws @date 2017年11月27日 下午3:27:01
     * @Title: diffYear
     * @author （guohao）
     * @version V1.0
     */
    public static int diffYear(Date startDate, Date endDate) {
        Calendar cale1 = Calendar.getInstance();
        Calendar cale2 = Calendar.getInstance();
        cale1.setTime(startDate);
        cale2.setTime(endDate);

        int i = cale1.get(Calendar.YEAR);
        int j = cale2.get(Calendar.YEAR);
        return Math.abs(i - j);
    }

    /**
     * 判断某一时间是否为今天的某一时间
     *
     * @param date
     * @return
     */
    public static boolean isToday(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(date);
        String now = sdf.format(new Date());
        if (dateStr.equals(now)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 求开始截至日期之间的天数差.
     *
     * @param d1 开始日期
     * @param d2 截至日期
     * @return 返回相差天数
     */
    public static int getDaysInterval(Date d1, Date d2) {
        if (d1 == null || d2 == null)
            return 0;
        Date[] d = new Date[2];
        d[0] = d1;
        d[1] = d2;
        Calendar[] cal = new Calendar[2];
        for (int i = 0; i < cal.length; i++) {
            cal[i] = Calendar.getInstance();
            cal[i].setTime(d[i]);
            cal[i].set(Calendar.HOUR_OF_DAY, 0);
            cal[i].set(Calendar.MINUTE, 0);
            cal[i].set(Calendar.SECOND, 0);
        }
        long m = cal[0].getTime().getTime();
        long n = cal[1].getTime().getTime();
        int ret = (int) Math.abs((m - n) / 1000 / 3600 / 24);
        return ret;
    }

    /**
     * Description:指定日期加或减days天
     *
     * @param date1 日期
     * @param days 天数
     * @return @since：2007-12-17 下午03:47:12
     */
    public static Date addDay(Date date1, int days) {
        Calendar date = Calendar.getInstance();
        date.setTime(date1);
        date.add(Calendar.DAY_OF_YEAR, days);
        return date.getTime();
    }

    public static Date addWeek(Date date1, int week) {
        Calendar date = Calendar.getInstance();
        date.setTime(date1);
        date.add(Calendar.WEEK_OF_YEAR, week);
        return date.getTime();
    }

    public static Date addMinute(Date date1, int minute) {
        Calendar date = Calendar.getInstance();
        date.setTime(date1);
        date.add(Calendar.MINUTE, minute);
        return date.getTime();
    }

    public static Date addMonth(Date date, int monthNum) {
        Calendar month = Calendar.getInstance();
        month.setTime(date);
        month.add(Calendar.MONTH, monthNum);
        month.getTime();
        return month.getTime();
    }

    public static Date addYear(Date date, int yearNum) {
        Calendar year = Calendar.getInstance();
        year.setTime(date);
        year.add(Calendar.YEAR, yearNum);
        return year.getTime();
    }

    /**
     * 获取某天的开始时间
     *
     * @return
     */
    public static Date getDateStart(Date date) {
        Calendar start = new GregorianCalendar();
        start.setTime(date);
        start.set(Calendar.HOUR_OF_DAY, 0);
        start.set(Calendar.MINUTE, 0);
        start.set(Calendar.SECOND, 0);
        start.set(Calendar.MILLISECOND, 0);
        return start.getTime();
    }

    /**
     * 获取某天的结束时间
     *
     * @return
     */
    public static Date getDateEnd(Date date) {
        Calendar end = new GregorianCalendar();
        end.setTime(date);
        end.set(Calendar.HOUR_OF_DAY, 23);
        end.set(Calendar.MINUTE, 59);
        end.set(Calendar.SECOND, 59);
        end.set(Calendar.MILLISECOND, 999);
        return end.getTime();
    }

    /**
     * 获取本月的开始日期
     *
     * @param date
     * @return
     */
    public static Date getWeekStartDate(Date date) {
        Calendar cale = new GregorianCalendar();
        cale.setTime(date);
        cale.set(Calendar.DAY_OF_WEEK, 1);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();
    }

    /**
     * 获取本月的开始日期
     *
     * @param date
     * @return
     */
    public static Date getMonthStartDate(Date date) {
        Calendar cale = new GregorianCalendar();
        cale.setTime(date);
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();
    }

    /**
     * 获取本月的结束日期
     *
     * @return
     */
    public static Date getMonthEndDate(Date date) {
        Calendar cale = new GregorianCalendar();
        cale.setTime(date);
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();
    }

    public static String getBabyBirthday(Date babyBirthday) {
        if (babyBirthday == null) {
            return "";
        }
        String format = DurationFormatUtils.formatPeriod(babyBirthday.getTime(), new Date().getTime(), "y-M-d");

        String[] set = format.split("-");

        if (Integer.parseInt(set[0]) == 0) {
            if (Integer.parseInt(set[2]) > 0) {

                return (Integer.parseInt(set[1]) + 1) + "个月";
            }
            if (Integer.parseInt(set[1]) == 0) {

                return (Integer.parseInt(set[1]) + 1) + "个月";
            }
            return set[1] + "个月";
        } else {
            if (Integer.parseInt(set[2]) > 0) {
                if (Integer.parseInt(set[1]) == 0) {

                    return set[0] + "岁";
                }
                return set[0] + "岁" + (Integer.parseInt(set[1])) + "个月";
            }
            if (Integer.parseInt(set[1]) > 0) {

                return set[0] + "岁" + set[1] + "个月";
            } else {
                return set[0] + "岁";

            }
        }

    }

    /**
     * 判断两日期是否为同一天
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDate(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
        boolean isSameDate = isSameMonth && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);

        return isSameDate;
    }

    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     *
     * @param str1 时间参数 1 格式：1990-01-01 12:00:00
     * @param str2 时间参数 2 格式：2009-01-01 12:00:00
     * @return long[] 返回值为：{天, 时, 分, 秒}
     */
    public static long[] getDistanceTimes(String str1, String str2) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date one;
        Date two;
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        try {
            one = df.parse(str1);
            two = df.parse(str2);
            long time1 = one.getTime();
            long time2 = two.getTime();
            long diff;
            if (time1 < time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24);
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        long[] times = {day, hour, min, sec};
        return times;
    }

    public static long[] getDistanceTimes(Date one, Date two) {
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        long time1 = one.getTime();
        long time2 = two.getTime();
        long diff;
        if (time1 < time2) {
            diff = time2 - time1;
        } else {
            diff = time1 - time2;
        }
        day = diff / (24 * 60 * 60 * 1000);
        hour = (diff / (60 * 60 * 1000) - day * 24);
        min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
        sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long[] times = {day, hour, min, sec};
        return times;
    }

    public static Boolean isCurrentMonth(Date date) {
        return isSameMonth(date, new Date());
    }

    public static Boolean isSameMonth(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal1.setTime(date2);
        int i = cal1.get(Calendar.MONTH);
        int j = cal2.get(Calendar.MONTH);
        if (i == j) {
            return true;
        }
        return false;
    }

    public static Date getYearStartDate(Date date) {
        Calendar cale = new GregorianCalendar();
        cale.setTime(date);
        cale.add(Calendar.YEAR, 0);
        cale.set(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();

    }

    public static Date getYearEndDate(Date date) {
        Calendar cale = new GregorianCalendar();
        cale.setTime(date);
        cale.add(Calendar.YEAR, 1);
        cale.set(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();

    }

    public static Integer getMonth(Date date) {
        Calendar cale = new GregorianCalendar();
        cale.setTime(date);
        return cale.get(Calendar.MONTH) + 1;
    }

    public static int getWeekDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        return day == 1 ? 7 : day - 1;
    }

    public static Date getNextWeekDate(int weekDay) {
        Date date = DateConvertUtils.getDateStart(new Date());
        int now = getWeekDay(date);
        return DateConvertUtils.addDay(date, 7 - now + weekDay);
    }

    /**
     * 获取当前周几 日期
     *
     * @param weekDay 周几
     * @return 日期
     */
    public static Date getCurrentWeekDate(int weekDay) {
        Date date = DateConvertUtils.getDateStart(new Date());
        int now = getWeekDay(date);

        return DateConvertUtils.addDay(date, weekDay - now);
    }

    public static String diffString(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        long sec = diff % nd % nh % nm / ns;
        StringBuilder stringBuilder = new StringBuilder();
        if (day != 0) {
            stringBuilder.append(Math.abs(day)).append("天");
        }
        if (hour != 0) {
            stringBuilder.append(Math.abs(hour)).append("小时");
        }
        if (min != 0) {
            stringBuilder.append(Math.abs(min)).append("分钟");
        }
        if (sec != 0) {
            stringBuilder.append(Math.abs(sec)).append("秒");
        }
        if (stringBuilder.length() == 0) {
            return "0秒";
        }
        return stringBuilder.toString();
    }

}
